﻿/************************************************************************
 * SMLib - State Model Library
 * Copyright (C) 2012-2013 Ali Khalili (khalili_DOT_ir_@SIGN_gmail_DOT_com)
 * **********************************************************************
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License (LGPL) published 
 * by the Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version. This program is distributed without any
 * warranty. See the GNU Lesser General Public License for more details. 
 * ***********************************************************************
 * File         :     SMLib\Base\DiGraph.cs
 * Description  :      Directed Graph
 * Change log   :     -2011: First version (originally, it was part of SimGine library)
 * To Do        :
 ************************************************************************/
using System;
using System.Collections.Generic;
//using System.Linq.Expressions;

namespace SMLib.Base
{
    /// <summary>
    /// Directed Graph
    /// </summary>
    /// <typeparam name="STATETYPE">Type of states</typeparam>
    /// <typeparam name="TRANSITIONTYPE">Type of transitions</typeparam>
    public abstract class DiGraph<STATETYPE, TRANSITIONTYPE>
        : IDiGraph<STATETYPE, TRANSITIONTYPE>
    {
        protected List<STATETYPE> states;

        /// <summary>
        /// Constructor
        /// </summary>
        public DiGraph()
        {
            states = new List<STATETYPE>();
        }

        #region =-[ Working with States ]=-

        /// <summary>
        /// Get all states
        /// </summary>
        /// <returns></returns>
        public List<STATETYPE> GetStates()
        {
            return states;
        }

        /// <summary>
        /// Add a state
        /// </summary>
        /// <param name="state">the state to be added</param>
        public void AddState(STATETYPE state)
        {
            //* Should we check that the state is already exists or not?
            states.Add(state);
        }

        /// <summary>
        /// Initialize the transition system with a state (which would be the initial state of the system)
        /// </summary>
        /// <param name="initialState">the initial state</param>
        public void Initialize(STATETYPE initialState)
        {
            if (states.Count == 0)
            {
                states.Add(initialState);
            }
            else
                throw new Exception("It is already initialized!");
        }

        /// <summary>
        /// Get the i-th state of transition system
        /// </summary>
        /// <param name="index">the index</param>
        /// <returns>i-th state of the system</returns>
        public STATETYPE this[int index]
        {
            get
            {
                if (index >= 0 && index < Size)
                    return states[index];
                else
                    return default(STATETYPE);
            }
        }

        /// <summary>
        /// Check weather the system has a state or not (Check by reference)
        /// </summary>
        /// <param name="state">the state to be checked</param>
        /// <returns>true if the system includes this state, false in other case</returns>
        public bool Contains(STATETYPE state)
        {
            return (IndexOf(state) > -1);
        }

        /// <summary>
        /// Find the index of a state (check by reference)
        /// </summary>
        /// <param name="state">the state to be found</param>
        /// <returns>index of state</returns>
        public int IndexOf(STATETYPE state)
        {
            for (int i = 0; i < states.Count; i++)
            {
                //* check by reference!
                if (object.ReferenceEquals(state, states[i]))
                //* if (state.Equals(states[i]))
                {
                    return i;
                }
            }
            return -1;
        }

        /// <summary>
        /// Number of states
        /// </summary>
        public int Size
        {
            get
            {
                return states.Count;
            }
        }
        #endregion

        #region IGraph<STATETYPE,TRANSITIONTYPE> Members

        public List<STATETYPE> GetAllStates()
        {
            return states;
        }

        public abstract STATETYPE DestinationOf(TRANSITIONTYPE t);




        public List<TRANSITIONTYPE> TransitionsOf(STATETYPE st)
        {
            return ((IState<TRANSITIONTYPE>)st).Transitions;
        }

        #endregion
        
        public TRANSITIONTYPE TransitionsOf(int index)
        {
        	throw new NotImplementedException();
        }
        
        public STATETYPE InitialState
        {
	        get
	        {
	        	return this[0];
	        }
        }
        
        
    }

    /*

    /// <summary>
    /// A Transition System
    /// </summary>
    /// <typeparam name="STATETYPE">Type of states</typeparam>
    /// <typeparam name="TRANSITIONTYPE">Type of transitions</typeparam>
    public abstract class TranSys<STATETYPE, TRANSITIONTYPE> :
        DiGraph<STATETYPE, TRANSITIONTYPE>
        //ITransitionSystem<STATETYPE, TRANSITIONTYPE, INPUTTYPE>
        //where TRANSITIONTYPE : ITransition<STATETYPE>
    //where STATETYPE : IState<TRANSITIONTYPE>
    {
        /// <summary>
        /// The initial state of transition system
        /// </summary>
        public STATETYPE InitialState
        {
            get
            {
                return states[0];
            }
        }
    }


    /// <summary>
    /// Labeled Transition System (LTS)
    /// </summary>
    /// <typeparam name="STATETYPE"></typeparam>
    /// <typeparam name="TRANSITIONTYPE"></typeparam>
    public abstract class LabeledTranSys<STATETYPE, LABELTYPE> :
        TranSys<STATETYPE, LABELTYPE>
        //where LABELTYPE : ILabeledTransition<STATETYPE, LABELTYPE>
    {


    }

    /// <summary>
    /// A Transition System
    /// <remarks>
    /// A transition system is represented by a rooted directed graph
    /// </remarks>
    /// </summary>
    public abstract class TranSys
        : TranSys<IStateContainer, ITransition>
    {

    }
    */
}
